#include <sys/unistd.h>
#include <mm/mm.h>
#include <mm/vma.h>
#include <mm/valloc.h>

#define LOG_TAG "Tests"
#include <log.h>

void test_open_read() {
    int fd = open("/root/boot/grub/grub.cfg", 0);
    LOGP("fd=%d\n", fd);
    char buf[32] = { 0 };
    int errno = read(fd, buf, 32);
    assert(errno == 32);
    for (int i = 0; i < 32; i++) {
        if (!is_visible(buf[i])) {
            buf[i] = ' ';
        }
    }
    LOGP("%s\n", buf);
}

void test_readdir() {
    int fd = open("/root/boot", 0);
    dirent_t d = (dirent_t){
        .d_offset = 0
    };
    while (readdir(fd, &d) == 1) {
        LOGP("%s\n", d.d_name);
    }
}

int do_swap_out(page_t* page);
void test_swap() {
    struct mm* mm = valloc(sizeof(struct mm));
    *mm = (struct mm){
        .page_count = 1,
        .vma_count = 1,
        .proc = cur_proc,
    };
    mm->proc = cur_proc;
    cur_proc->mm = mm;
    atomic_init(&mm->ref_count, 1);
    mutex_init(&mm->lock);

    struct vma* vma = vma_alloc();
    vma->start = 0xA0000000;
    vma->end = 0xB0000000;
    vma->mm = mm;
    vma->flags = VMA_PRIVATE | VMA_WRITE | VMA_READ;

    vma->next = mm->vma_list;
    if (vma->next) {
        vma->next->prev = vma;
    }
    mm->vma_list = vma;

    struct avm* avm = avm_alloc();
    avm->root = avm;
    vma->avm = avm;

    struct avm_chain* avc = avm_chain_alloc();
    avc->avm = avm;
    avc->vma = vma;

    list_append(&vma->avm_chain, &avc->same_avm);
    list_append(&avm->avc_list, &avc->same_avm);

    uptr* p = (uptr*)(vma->start + 0x1000);
    p[0] = 12345678;

    pg_entry_t* pte = &PTE_ENTRY(TBL_BASE_VADDR, (vma->start + 0x1000) >> 12);
    page_t* page = page_query(pte->frame << PG_SIZE_BITS);
    assert(p[0] == 12345678);
    int errno = do_swap_out(page);
    LOGW("swap out errno: %d\n", errno);

    LOGW("p[0]: %d\n", p[0]);
}

void tests() {
    
}
